package com.lottery.controller;

import com.lottery.model.CombinationRequest;
import com.lottery.model.CombinationResult;
import com.lottery.model.Match;
import com.lottery.service.LotteryService;
import com.lottery.service.PythonStyleImageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


@RestController
@RequestMapping("/api/lottery")
public class LotteryController {

    @Autowired
    private LotteryService lotteryService;
    @Autowired
    private PythonStyleImageService imageService;

    @GetMapping("/matches")
    public ResponseEntity<List<Match>> getMatches(
            @RequestParam(required = false) String url,
            @RequestParam(required = false) String drawNum) {
        List<Match> matches = lotteryService.getMatches(url, drawNum);
        return ResponseEntity.ok(matches);
    }

    @PostMapping("/generate")
    public ResponseEntity<CombinationResult> generateCombinations(@RequestBody CombinationRequest request) {
        try {
            return ResponseEntity.ok(lotteryService.generateCombinations(request));
        }
        catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(null);
        }
        catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    /**
     * 生成与Python版本一致的组合图片
     */
    @PostMapping(value = "/generate/image", produces = MediaType.IMAGE_PNG_VALUE)
    public ResponseEntity<byte[]> generateCombinationImage(@RequestBody CombinationResult result) {
        try {
            byte[] imageData = imageService.generateCombinationImage(result);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment",
                    "lottery-combinations-" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".png");

            return new ResponseEntity<>(imageData, headers, HttpStatus.OK);
        }
        catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 多图片压缩下载
     */
    @PostMapping(value = "/generate/images/zip", produces = "application/zip")
    public ResponseEntity<byte[]> generateCombinationImagesZip(
            @RequestBody CombinationResult result) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zos = new ZipOutputStream(baos)) {

            // 为每个组合生成单独图片并添加到ZIP
            for (int i = 0; i < result.getCombinations().size(); i++) {
                // 创建仅包含当前组合的临时结果对象
                CombinationResult singleResult = new CombinationResult(
                        Collections.singletonList(result.getCombinations().get(i)),
                        1,
                        result.getTotalBets(),
                        result.getTotalAmount()
                );

                byte[] imageData = imageService.generateCombinationImage(singleResult);

                // 创建ZIP条目
                ZipEntry entry = new ZipEntry(
                        String.format("组合%d-%s.png",
                                i + 1,
                                new SimpleDateFormat("yyyyMMdd").format(new Date()))
                );
                zos.putNextEntry(entry);
                zos.write(imageData);
                zos.closeEntry();
            }

            zos.finish();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment",
                    "彩票组合-" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".zip");

            return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.OK);
        }
        catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping("/draws")
    public ResponseEntity<List<String>> getDrawNumbers() {
        try {
            List<String> draws = lotteryService.getRecentDrawNumbers();
            return ResponseEntity.ok(draws);
        }
        catch (Exception e) {
            return ResponseEntity.ok(Arrays.asList("25129", "25130", "25131", "25132")); // 默认期号
        }
    }

    @GetMapping("/newMatches")
    public ResponseEntity<Object> getNewMatches(@RequestParam String url) {
        // 1. 校验url合法性，防止恶意请求
        if (!url.startsWith("https://webapi.sporttery.cn/")) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
                    .body("仅允许代理sporttery.cn域名的请求");
        }

        try {
            WebClient webClient = WebClient.builder()
                    // 关键：开启GZIP解压，自动处理压缩响应
                    .codecs(configurer -> configurer.defaultCodecs().enableLoggingRequestDetails(true))
                    .clientConnector(
                            new ReactorClientHttpConnector(
                                    HttpClient.create()
                                            .responseTimeout(Duration.ofSeconds(10))
                                            .compress(true) // 开启GZIP解压，解决压缩数据解析问题
                            )
                    )
                    // 补充请求头，模拟浏览器行为
                    .defaultHeader("User-Agent", lotteryService.getRandomUserAgent())
                    .defaultHeader("Referer", "https://www.sporttery.cn/")
                    .defaultHeader("X-Requested-With", "XMLHttpRequest")
                    .defaultHeader("Accept", "application/json, text/javascript, */*; q=0.01")
                    .defaultHeader("Accept-Encoding", "gzip, deflate, br") // 告诉服务器支持GZIP压缩
                    .defaultHeader("Accept-Language", "zh-CN,zh;q=0.9")
                    .build();

            // 2. 发起请求并解析JSON
            Map<String, Object> response = webClient.get()
                    .uri(url)
                    .retrieve()
                    // 处理4xx/5xx错误状态码
                    .onStatus(HttpStatus::isError, resp ->
                            Mono.error(new RuntimeException("目标接口返回错误：" + resp.statusCode()))
                    )
                    .bodyToMono(Map.class)
                    .block();

            return ResponseEntity.ok(response);

        }
        catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("代理请求失败：" + e.getMessage());
        }
    }
}